package com.fqgj.sentry.controller.antiFraud.response.anti.tree;

import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.report.statistics.entity.BiAttrBlackListEntity;
import com.fqgj.sentry.biz.antiFraud.domain.OrderVo;
import com.fqgj.sentry.biz.antiFraud.domain.PropertyTypeEnums;
import com.fqgj.sentry.biz.antiFraud.domain.PropertyVo;
import com.fqgj.sentry.controller.antiFraud.OrderRelationController;
import com.fqgj.sentry.controller.antiFraud.response.anti.AntiFraudDataUtil;
import com.fqgj.sentry.controller.antiFraud.response.anti.OrderInfo;
import com.fqgj.sentry.controller.antiFraud.response.anti.tree.gps.Data;
import com.fqgj.sentry.controller.antiFraud.response.anti.tree.gps.Item;
import com.fqgj.sentry.controller.antiFraud.response.anti.tree.gps.RelationGpsInfo;
import com.fqgj.sentry.statistics.service.RiskAttributeService;
import com.google.gson.Gson;
import com.fqgj.log.interfaces.Log;
import com.fqgj.log.factory.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by liupengpeng on 2017/10/17.
 */
@Component
public class NodeTreeDataUtil implements Serializable {
    public static final Log LOGGER = LogFactory.getLog(OrderRelationController.class);

    @Autowired
    private RiskAttributeService riskAttributeService;


    /**
     * * 画订单--属性--订单
     */
    public AntiRelationInfo drawAntiRelationInfo(Long merchantId, Long appId,
                                                 OrderVo orderVo, Integer layer) {
        AntiRelationInfo antiRelationInfo = new AntiRelationInfo();
        RelationGpsInfo relationGpsInfo = new RelationGpsInfo();

//        antiRelationInfo.setRelationGpsInfo(RelationGpsInfo.getRelationGpsInfo());

        NodeTreeInfo firstTree = new NodeTreeInfo(
                orderVo.getRealName() + "(" + orderVo.getApplyDate() + ")", 2,
                orderVo.getNo(), getOrderInfo(orderVo), NodeLineTypeEnum.REAL_LINE.getType(), "", getOrderNodeColor(orderVo));
        List<NodeTreeInfo> firstChildren = new ArrayList<>();

        List<PropertyVo> propertyVoList = orderVo.getPropertyVoList();
        List<Item> itemList = new ArrayList<>();
        Map<String, Double[]> geoCoordMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(propertyVoList)) {
            for (PropertyVo propertyVo : propertyVoList) {


                String lineColor = propertyVo.getPropertyTypeEnums().getLineColor();
                String propertyDesc = propertyVo.getPropertyTypeEnums().getDesc();
                if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile1) {
                    propertyDesc = propertyDesc + "(" + orderVo.getContactMobile1() + ")";
                }
                if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile2) {
                    propertyDesc = propertyDesc + "(" + orderVo.getContactMobile2() + ")";
                }
                if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.qq) {
                    propertyDesc = propertyDesc + "(" + orderVo.getQq() + ")";
                }
                NodeTreeInfo secondTree = new NodeTreeInfo(propertyDesc,
                        1, propertyVo.getNo(), getOrderInfo(propertyVo),
                        NodeLineTypeEnum.REAL_LINE.getType(), lineColor, getPropertyNodeColor(merchantId, appId, orderVo, propertyVo));
                List<NodeTreeInfo> secondChildren = new ArrayList<>();

                List<OrderVo> propertyOrderList = propertyVo.getOrderVoList();
                for (OrderVo propertyOrder : propertyOrderList) {
                    NodeTreeInfo thirdTree = new NodeTreeInfo(propertyOrder.getRealName() + "(" + propertyOrder.getApplyDate() + ")",
                            2, propertyOrder.getNo(), getOrderInfo(propertyOrder),
                            getLineType(propertyVo, orderVo, propertyOrder), lineColor, getOrderNodeColor(propertyOrder));
                    secondChildren.add(thirdTree);
                    putGpsData(geoCoordMap, itemList, propertyOrder, propertyVo);
                    Integer layerTemp = layer - 1;
                    if (layerTemp > 0) {
                        nodeAddChildByLayer(merchantId, appId, geoCoordMap, itemList, thirdTree, propertyOrder, propertyVo, layerTemp);
                    }
                }
                secondTree.setChildren(secondChildren);
                firstChildren.add(secondTree);
            }
        }
        firstTree.setChildren(firstChildren);

        antiRelationInfo.setRelationGpsInfo(relationGpsInfo.setGeoCoordMap(geoCoordMap).setItemList(itemList));
        antiRelationInfo.setNodeTreeInfo(firstTree);
        return antiRelationInfo;
    }

    /**
     * * 画订单--属性--订单
     */
    public void deleteSameProperty(NodeTreeInfo nodeTreeInfo, Integer layer) {
        try {
            if (layer < 2) {
                return;
            }
            List<NodeTreeInfo> firstPropertyList = nodeTreeInfo.getChildren();
            List<String> firstPropertyStrList = new ArrayList<>();
            for (NodeTreeInfo firstProperty : firstPropertyList) {
                firstPropertyStrList.add(firstProperty.getName());
            }
            for (NodeTreeInfo firstProperty : firstPropertyList) {
                List<NodeTreeInfo> firstPropertyOrderList = firstProperty.getChildren();
                for (NodeTreeInfo firstPropertyOrder : firstPropertyOrderList) {
                    Integer layerTemp = layer--;
                    if (layer > 2) {
                        this.deleteSameProperty(firstPropertyOrder, layerTemp);
                    }
                    List<NodeTreeInfo> firstPropertyOrderPropertyList = firstPropertyOrder.getChildren();
                    List<NodeTreeInfo> firstPropertyOrderPropertyListTemp = new ArrayList<>();
                    for (NodeTreeInfo firstPropertyOrderProperty : firstPropertyOrderPropertyList) {
                        if (!firstPropertyStrList.contains(firstPropertyOrderProperty.getName())) {
                            firstPropertyOrderPropertyListTemp.add(firstPropertyOrderProperty);
                        }
                    }
                    firstPropertyOrder.setChildren(firstPropertyOrderPropertyListTemp);
                }
//                List<NodeTreeInfo> firstPropertyOrderListTemp = new ArrayList<>();
                //并排的订单  同一个用户出去的属性   只有一个订单出去
//                Set<String> user = new HashSet<>();
//                for (NodeTreeInfo firstPropertyOrder : firstPropertyOrderList) {
//                    if (!user.contains(firstPropertyOrder.getOrderInfo().getUserNo())) {
//                        user.add(firstPropertyOrder.getOrderInfo().getUserNo());
//                        firstPropertyOrderListTemp.add(firstPropertyOrder);
//                    }
//
//                }
//                firstProperty.setChildren(firstPropertyOrderListTemp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * * 处理节点收缩管理
     */
    public AntiRelationInfo relationExtendInfo(AntiRelationInfo antiRelationInfo) {
        NodeTreeInfo nodeTreeInfo = antiRelationInfo.getNodeTreeInfo();
        List<NodeTreeInfo> firstPropertyChildren = nodeTreeInfo.getChildren();

        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(firstPropertyChildren)) {

            for (NodeTreeInfo firstPropertyChild : firstPropertyChildren) {
                List<NodeTreeInfo> firstOrderChildren = firstPropertyChild.getChildren();

                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(firstOrderChildren)) {
                    if (firstOrderChildren.size() > 10) {
                        firstPropertyChild.setExtend(false);
                    }
                    //查询二级属性数  订单数
                    for (NodeTreeInfo firstOrderChild : firstOrderChildren) {

                        List<NodeTreeInfo> secondPropertyChildren = firstOrderChild.getChildren();
                        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(secondPropertyChildren)) {
                            for (NodeTreeInfo secondPropertyChild : secondPropertyChildren) {

                                List<NodeTreeInfo> secondOrderChildren = secondPropertyChild.getChildren();
                                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(secondOrderChildren)) {

                                    if (secondOrderChildren.size() > 10) {
                                        secondPropertyChild.setExtend(false);
                                    }
                                    //查询三级属性数  订单数
                                    for (NodeTreeInfo secondOrderChild : secondOrderChildren) {

                                        List<NodeTreeInfo> thirdPropertyChildren = secondOrderChild.getChildren();
                                        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(thirdPropertyChildren)) {
                                            for (NodeTreeInfo thirdPropertyChild : thirdPropertyChildren) {
                                                List<NodeTreeInfo> thirdOrderChildren = thirdPropertyChild.getChildren();
                                                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(thirdOrderChildren)) {

                                                    if (thirdOrderChildren.size() > 10) {
                                                        thirdPropertyChild.setExtend(false);
                                                    }
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }
                }

            }

        }
        return antiRelationInfo;
    }

    private String getOrderNodeColor(OrderVo orderVo) {
        //白色
        String color = "#FFFFFF";
        if (orderVo.getSuccessDate() != null && orderVo.getRepaymentDate() != null) {
            if (orderVo.getActualRepaymentDate() != null) {
                if (DateUtil.diffDate(orderVo.getActualRepaymentDate(), orderVo.getRepaymentDate()) > 0) {
                    color = "#FF0000";
                }
            } else {
                if (DateUtil.diffDate(new Date(), orderVo.getRepaymentDate()) > 0) {
                    color = "#FF0000";
                }
            }
        }
        if (orderVo.getRiskResultType() != null && orderVo.getRiskResultType() == 1) {
            //灰色
            color = "#292929";
        }
        return color;

    }

    private String getPropertyNodeColor(Long merchantId, Long appId,
                                        OrderVo orderVo, PropertyVo propertyVo) {

        String color = "#FFFFFF";
        String value = "";
        switch (propertyVo.getPropertyTypeEnums()) {
            case ip:
                value = orderVo.getIp();
                break;
            case wifi:
                value = orderVo.getWifi();
                break;
            case email:
                value = orderVo.getEmail();
                break;
            case device:
                value = orderVo.getClientId();
                break;
            case qq:
                value = orderVo.getQq();
                break;
            case identityNO:
                value = orderVo.getIdentityNO();
                break;
            case companyName:
                value = orderVo.getCompanyName();
                break;
            case companyPhone:
                value = orderVo.getCompanyPhone();
                break;
            case contactMobile1:
                value = orderVo.getContactMobile1();
                break;
            case contactMobile2:
                value = orderVo.getContactMobile2();
                break;
        }

        if (StringUtils.isNotEmpty(value)) {

            BiAttrBlackListEntity biAttrBlackListEntity = riskAttributeService.findByValueAndType(merchantId, appId,
                    propertyVo.getPropertyTypeEnums().getType(), value);
            if (biAttrBlackListEntity != null) {
//                LOGGER.error("merchantId:{},appId:{},type:{},value:{}", merchantId, appId,
//                        propertyVo.getPropertyTypeEnums().getType(), value);
                color = "#8F8F8F";
            }
        }
        return color;
    }

    private Integer getLineType(PropertyVo propertyVo, OrderVo parentOrder, OrderVo thisOrder) {
        Integer lineType = NodeLineTypeEnum.REAL_LINE.getType();
        if (propertyVo.getPropertyTypeEnums() != null) {
            if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile1) {
                if (StringUtils.isNotEmpty(thisOrder.getContactName1())
                        && StringUtils.isNotEmpty(parentOrder.getContactName1())
                        && !thisOrder.getContactName1().equals(parentOrder.getContactName1())
                        ) {
                    lineType = NodeLineTypeEnum.UN_REAL_LINE.getType();
                }
            }
            if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile2) {
                if (StringUtils.isNotEmpty(thisOrder.getContactName2())
                        && StringUtils.isNotEmpty(parentOrder.getContactName2())
                        && !thisOrder.getContactName1().equals(parentOrder.getContactName2())
                        ) {
                    lineType = NodeLineTypeEnum.UN_REAL_LINE.getType();
                }
            }
        }
        return lineType;
    }


    /**
     * @param orderVo
     * @param propertyVo
     */
    private void putGpsData(Map<String, Double[]> geoCoordMap, List<Item> itemList, OrderVo orderVo, PropertyVo propertyVo) {

        if (StringUtils.isEmpty(orderVo.getCity())) {
            return;
        }
        Boolean needAdd = false;
        Double[] xy = new Double[]{orderVo.getLng(), orderVo.getLat()};
        geoCoordMap.put(orderVo.getCity(), xy);

        if (itemList == null) {
            itemList = new ArrayList<>();
        }
        String itemName = propertyVo.getPropertyTypeEnums().name();
        Item item = itemExists(itemList, itemName);
        if (item == null) {
            needAdd = true;
            item = new Item();
            item.setName(itemName);
        }

        List<Data> dataList = item.getData();
        if (dataList == null) {
            dataList = new ArrayList<>();

        }
        Data data = new Data();
        data.setName(orderVo.getCity());
        data.setValue(1);
        data.setApplyDate(orderVo.getApplyDate());
        data.setDataDesc(orderVo.getRealName() + "(" + orderVo.getApplyDate() + ")，订单号:" + orderVo.getOrderNo() + "gps地址：" + orderVo.getGpsAddress());
        dataList.add(data);
        item.setData(dataList);

        if (needAdd) {
            itemList.add(item);
        }

    }

    /**
     * @param itemList
     * @param itemName
     * @return
     */
    private Item itemExists(List<Item> itemList, String itemName) {
        for (Item i : itemList) {
            if (i.getName().equals(itemName)) return i;
        }
        return null;
    }

    private OrderInfo getOrderInfo(OrderVo order) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(order, orderInfo);

        Date successDate = order.getSuccessDate();
        Date repaymentDate = order.getRepaymentDate();
        Date actualRepaymentDate = order.getActualRepaymentDate();
        if (successDate != null) {
            orderInfo.setSuccessDate(sdf.format(successDate));
        }
        if (repaymentDate != null) {
            orderInfo.setRepaymentDate(sdf.format(repaymentDate));
        }
        if (actualRepaymentDate != null) {
            orderInfo.setActualRepaymentDate(sdf.format(actualRepaymentDate));
        }
        return orderInfo;
    }


    private OrderInfo getOrderInfo(PropertyVo propertyVo) {
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(propertyVo, orderInfo);
        return orderInfo;
    }

    /**
     * * 节点追加子节点
     */
    public NodeTreeInfo nodeAddChildByLayer(Long merchantId, Long appId,
                                            Map<String, Double[]> geoCoordMap,
                                            List<Item> itemList,
                                            NodeTreeInfo tree, OrderVo orderVo, PropertyVo parentProperty,
                                            Integer layer) {

        List<NodeTreeInfo> firstChildren = new ArrayList<>();

        List<PropertyVo> propertyVoList = orderVo.getPropertyVoList();
        if (CollectionUtils.isNotEmpty(propertyVoList)) {
            for (PropertyVo propertyVo : propertyVoList) {
                String propertyDesc = propertyVo.getPropertyTypeEnums().getDesc();
                if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile1) {
                    propertyDesc = propertyDesc + "(" + orderVo.getContactMobile1() + ")";
                }
                if (propertyVo.getPropertyTypeEnums() == PropertyTypeEnums.contactMobile2) {
                    propertyDesc = propertyDesc + "(" + orderVo.getContactMobile2() + ")";
                }
                String propertyColor = propertyVo.getPropertyTypeEnums().getLineColor();
                NodeTreeInfo secondTree = new NodeTreeInfo(propertyDesc,
                        NodeTypeEnum.PROPERTY.getType(), propertyVo.getNo(), getOrderInfo(propertyVo),
                        NodeLineTypeEnum.REAL_LINE.getType(), propertyColor, getPropertyNodeColor(merchantId, appId, orderVo, propertyVo));
                List<NodeTreeInfo> secondChildren = new ArrayList<>();

                List<OrderVo> propertyOrderList = propertyVo.getOrderVoList();
                for (OrderVo propertyOrder : propertyOrderList) {
                    NodeTreeInfo thirdTree = new NodeTreeInfo(propertyOrder.getRealName() + "(" + propertyOrder.getApplyDate() + ")",
                            NodeTypeEnum.ORDER.getType(), propertyOrder.getNo(), getOrderInfo(propertyOrder),
                            getLineType(propertyVo, orderVo, propertyOrder), propertyColor, getOrderNodeColor(propertyOrder));
                    secondChildren.add(thirdTree);

                    putGpsData(geoCoordMap, itemList, propertyOrder, parentProperty);
                    Integer layerTemp = layer - 1;
                    if (layerTemp > 0) {
                        nodeAddChildByLayer(merchantId, appId, geoCoordMap, itemList, thirdTree, propertyOrder, propertyVo, layerTemp);
                    }
                }
                secondTree.setChildren(secondChildren);
                firstChildren.add(secondTree);
            }
        }
        tree.setChildren(firstChildren);
        return tree;
    }

    public void main(String[] args) {
        OrderVo orderVo = AntiFraudDataUtil.getAntiFraudVo();
        AntiRelationInfo antiRelationInfo = new NodeTreeDataUtil().drawAntiRelationInfo(1L, 1L, orderVo, 2);
        System.out.println(new Gson().toJson(antiRelationInfo));

    }
}
